home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / taito_f2.c < prev    next >
C/C++ Source or Header  |  2000-05-25  |  14KB  |  569 lines

  1. #include "driver.h"
  2. #include "vidhrdw/generic.h"
  3.  
  4. unsigned char *taitof2_scrollx;
  5. unsigned char *taitof2_scrolly;
  6. unsigned char *f2_backgroundram;
  7. size_t f2_backgroundram_size;
  8. unsigned char *f2_foregroundram;
  9. size_t f2_foregroundram_size;
  10. unsigned char *f2_textram;
  11. size_t f2_textram_size;
  12. unsigned char *taitof2_characterram;
  13. static unsigned char *char_dirty;    /* 256 chars */
  14. size_t f2_characterram_size;
  15. static unsigned char *text_dirty;
  16. static unsigned char *bg_dirty;
  17. static unsigned char *fg_dirty;
  18. size_t f2_paletteram_size;
  19.  
  20. static struct osd_bitmap *tmpbitmap2;
  21. static struct osd_bitmap *tmpbitmap3;
  22. static int spritebank[8];
  23.  
  24. int taitof2_vh_start (void)
  25. {
  26.     char_dirty = malloc (f2_characterram_size/16);
  27.     if (!char_dirty) return 1;
  28.     memset (char_dirty,1,f2_characterram_size/16);
  29.  
  30.     text_dirty = malloc (f2_textram_size/2);
  31.     if (!text_dirty)
  32.     {
  33.         free (char_dirty);
  34.         return 1;
  35.     }
  36.  
  37.     bg_dirty = malloc (f2_backgroundram_size/4);
  38.     if (!bg_dirty)
  39.     {
  40.         free (char_dirty);
  41.         free (text_dirty);
  42.         return 1;
  43.     }
  44.     memset (bg_dirty,1,f2_backgroundram_size/4);
  45.  
  46.     fg_dirty = malloc (f2_foregroundram_size/4);
  47.     if (!fg_dirty)
  48.     {
  49.         free (char_dirty);
  50.         free (text_dirty);
  51.         free (bg_dirty);
  52.         return 1;
  53.     }
  54.     memset (fg_dirty,1,f2_foregroundram_size/4);
  55.  
  56.     /* create a temporary bitmap slightly larger than the screen for the background */
  57.     if ((tmpbitmap = osd_create_bitmap(64*8, 64*8)) == 0)
  58.     {
  59.         free (char_dirty);
  60.         free (text_dirty);
  61.         free (bg_dirty);
  62.         free (fg_dirty);
  63.         return 1;
  64.     }
  65.  
  66.     /* create a temporary bitmap slightly larger than the screen for the foreground */
  67.     if ((tmpbitmap2 = osd_create_bitmap(64*8, 64*8)) == 0)
  68.     {
  69.         free (char_dirty);
  70.         free (text_dirty);
  71.         free (bg_dirty);
  72.         free (fg_dirty);
  73.         osd_free_bitmap (tmpbitmap);
  74.         return 1;
  75.     }
  76.  
  77.     /* create a temporary bitmap slightly larger than the screen for the text layer */
  78.     if ((tmpbitmap3 = osd_create_bitmap(64*8, 64*8)) == 0)
  79.     {
  80.         free (char_dirty);
  81.         free (text_dirty);
  82.         free (bg_dirty);
  83.         free (fg_dirty);
  84.         osd_free_bitmap (tmpbitmap);
  85.         osd_free_bitmap (tmpbitmap2);
  86.         return 1;
  87.     }
  88.  
  89.     {
  90.         int i;
  91.  
  92.         for (i = 0; i < 8; i ++)
  93.             spritebank[i] = 0x400 * i;
  94.     }
  95.  
  96.     {
  97.         int i;
  98.  
  99.         memset (paletteram, 0, f2_paletteram_size); /* probably not needed */
  100.         for (i = 0; i < f2_paletteram_size/2; i++)
  101.             palette_change_color (i,0,0,0);
  102.     }
  103.  
  104.     return 0;
  105. }
  106.  
  107. void taitof2_vh_stop (void)
  108. {
  109.     free (char_dirty);
  110.     free (text_dirty);
  111.     free (bg_dirty);
  112.     free (fg_dirty);
  113.     osd_free_bitmap (tmpbitmap);
  114.     osd_free_bitmap (tmpbitmap2);
  115.     osd_free_bitmap (tmpbitmap3);
  116. }
  117.  
  118. /* we have to straighten out the 16-bit word into bytes for gfxdecode() to work */
  119. READ_HANDLER( taitof2_characterram_r )
  120. {
  121.     int res;
  122.  
  123.     res = READ_WORD (&taitof2_characterram[offset]);
  124.  
  125.     #ifdef LSB_FIRST
  126.     res = ((res & 0x00ff) << 8) | ((res & 0xff00) >> 8);
  127.     #endif
  128.  
  129.     return res;
  130. }
  131.  
  132. WRITE_HANDLER( taitof2_characterram_w )
  133. {
  134.     int oldword = READ_WORD (&taitof2_characterram[offset]);
  135.     int newword;
  136.  
  137.  
  138.     #ifdef LSB_FIRST
  139.     data = ((data & 0x00ff00ff) << 8) | ((data & 0xff00ff00) >> 8);
  140.     #endif
  141.  
  142.     newword = COMBINE_WORD (oldword,data);
  143.     if (oldword != newword)
  144.     {
  145.         WRITE_WORD (&taitof2_characterram[offset],newword);
  146.         char_dirty[offset / 16] = 1;
  147.     }
  148. }
  149.  
  150. READ_HANDLER( taitof2_text_r )
  151. {
  152.     return READ_WORD(&f2_textram[offset]);
  153. }
  154.  
  155. WRITE_HANDLER( taitof2_text_w )
  156. {
  157.     int oldword = READ_WORD (&f2_textram[offset]);
  158.     int newword = COMBINE_WORD (oldword, data);
  159.  
  160.     if (oldword != newword)
  161.     {
  162.         WRITE_WORD (&f2_textram[offset],newword);
  163.         text_dirty[offset / 2] = 1;
  164.     }
  165. }
  166.  
  167. READ_HANDLER( taitof2_background_r )
  168. {
  169.     return READ_WORD(&f2_backgroundram[offset]);
  170. }
  171.  
  172. WRITE_HANDLER( taitof2_background_w )
  173. {
  174.     int oldword = READ_WORD (&f2_backgroundram[offset]);
  175.     int newword = COMBINE_WORD (oldword, data);
  176.  
  177.     if (oldword != newword)
  178.     {
  179.         WRITE_WORD (&f2_backgroundram[offset],newword);
  180.         bg_dirty[offset / 4] = 1;
  181.     }
  182. }
  183.  
  184. READ_HANDLER( taitof2_foreground_r )
  185. {
  186.     return READ_WORD(&f2_foregroundram[offset]);
  187. }
  188.  
  189. WRITE_HANDLER( taitof2_foreground_w )
  190. {
  191.     int oldword = READ_WORD (&f2_foregroundram[offset]);
  192.     int newword = COMBINE_WORD (oldword, data);
  193.  
  194.     if (oldword != newword)
  195.     {
  196.         WRITE_WORD (&f2_foregroundram[offset],newword);
  197.         fg_dirty[offset / 4] = 1;
  198.     }
  199. }
  200.  
  201. WRITE_HANDLER( taitof2_spritebank_w )
  202. {
  203.     logerror("bank %d, new value: %04x\n", offset >> 1, data << 10);
  204.     if ((offset >> 1) < 4) return;
  205. //    if (data == 0) data = (offset >> 1) * 0x400;
  206.     spritebank[offset >> 1] = data << 10;
  207. }
  208.  
  209. void taitof2_update_palette (void)
  210. {
  211.     int i;
  212.     int offs,code,color,spritecont;
  213.     unsigned short palette_map[256];
  214.  
  215.     memset (palette_map, 0, sizeof (palette_map));
  216.  
  217.     /* Background layer */
  218.     for (offs = 0;offs < f2_backgroundram_size;offs += 4)
  219.     {
  220.         int tile;
  221.  
  222.         tile = READ_WORD (&f2_backgroundram[offs + 2]);
  223.         color = (READ_WORD (&f2_backgroundram[offs]) & 0xff);
  224.  
  225.         palette_map[color] |= Machine->gfx[1]->pen_usage[tile];
  226.     }
  227.  
  228.     /* Background layer */
  229.     for (offs = 0;offs < f2_foregroundram_size;offs += 4)
  230.     {
  231.         int tile;
  232.  
  233.         tile = READ_WORD (&f2_foregroundram[offs + 2]);
  234.         color = (READ_WORD (&f2_foregroundram[offs]) & 0xff);
  235.  
  236.         palette_map[color] |= Machine->gfx[1]->pen_usage[tile];
  237.     }
  238.  
  239.     color = 0;
  240.  
  241.     /* Sprites */
  242.     for (offs = 0;offs < 0x3400;offs += 16)
  243.     {
  244.         spritecont = (READ_WORD(&videoram[offs+8]) & 0xff00) >> 8;
  245. //        if (!spritecont) continue;
  246.  
  247.         code = READ_WORD(&videoram[offs]) & 0x1fff;
  248.  
  249.         {
  250.             int bank;
  251.  
  252.             bank = (code & 0x1c00) >> 10;
  253.             code = spritebank[bank] + (code & 0x3ff);
  254.         }
  255.  
  256.         if ((spritecont & 0xf4) == 0)
  257.         {
  258.             color = READ_WORD(&videoram[offs+8]) & 0x00ff;
  259.         }
  260.         if (!code) continue;
  261.  
  262.         palette_map[color] |= Machine->gfx[0]->pen_usage[code];
  263.     }
  264.  
  265.     /* Do the text layer */
  266.     for (offs = 0;offs < 0x1000;offs += 2)
  267.     {
  268.         int tile;
  269.  
  270.         tile = READ_WORD (&f2_textram[offs]) & 0xff;
  271.         color = (READ_WORD (&f2_textram[offs]) & 0x0f00) >> 8;
  272.  
  273.         palette_map[color] |= Machine->gfx[2]->pen_usage[tile];
  274.     }
  275.  
  276.     /* Tell MAME about the color useage */
  277.     for (i = 0;i < 256;i++)
  278.     {
  279.         int usage = palette_map[i];
  280.         int j;
  281.  
  282.         if (usage)
  283.         {
  284.             palette_used_colors[i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  285.             for (j = 1; j < 16; j++)
  286.                 if (palette_map[i] & (1 << j))
  287.                     palette_used_colors[i * 16 + j] = PALETTE_COLOR_USED;
  288.                 else
  289.                     palette_used_colors[i * 16 + j] = PALETTE_COLOR_UNUSED;
  290.         }
  291.         else
  292.             memset(&palette_used_colors[i * 16],PALETTE_COLOR_UNUSED,16);
  293.     }
  294.  
  295.     if (palette_recalc ())
  296.     {
  297.         memset (text_dirty, 1, f2_textram_size/2);
  298.         memset (bg_dirty, 1, f2_backgroundram_size/4);
  299.         memset (fg_dirty, 1, f2_foregroundram_size/4);
  300.     }
  301. }
  302.  
  303. void taitof2_draw_sprites (struct osd_bitmap *bitmap)
  304. {
  305.     /*
  306.         Sprite format:
  307.         0000: 000xxxxxxxxxxxxx: tile code (0x0000 - 0x1fff)
  308.         0002: unused?
  309.         0004: 0000xxxxxxxxxxxx: x-coordinate absolute (-0x1ff to 0x01ff)
  310.               0x00000000000000: don't compensate for scrolling ??
  311.         0006: 0000xxxxxxxxxxxx: y-coordinate absolute (-0x1ff to 0x01ff)
  312.         0008: 00000000xxxxxxxx: color (0x00 - 0xff)
  313.               000000xx00000000: flipx & flipy
  314.               00000x0000000000: if clear, latch x & y coordinates, tile & color ?
  315.               0000x00000000000: if set, next sprite entry is part of sequence
  316.               000x000000000000: if clear, use latched y coordinate, else use current y
  317.               00x0000000000000: if set, y += 16
  318.               0x00000000000000: if clear, use latched x coordinate, else use current x
  319.               x000000000000000: if set, x += 16
  320.         000a - 000f : unused?
  321.  
  322.         Additionally, the first 3 sprite entries are configuration info instead of
  323.         actual sprites:
  324.  
  325.         offset 0x24: sprite x offset
  326.         offset 0x26: sprite y offset
  327.     */
  328.     int x,y,offs,code,color,spritecont,flipx,flipy;
  329.     int xcurrent,ycurrent;
  330.     int scroll1x, scroll1y;
  331.     int scrollx=0, scrolly=0;
  332.     int curx,cury;
  333.  
  334.     scroll1x = READ_WORD(&videoram[0x24]);
  335.     scroll1y = READ_WORD(&videoram[0x26]);
  336.  
  337.     x = y = 0;
  338.     xcurrent = ycurrent = 0;
  339.     color = 0;
  340.  
  341.     for (offs = 0x30;offs < 0x3400;offs += 16)
  342.     {
  343.         spritecont = (READ_WORD(&videoram[offs+8]) & 0xff00) >> 8;
  344.  
  345.         if ((spritecont & 0xf4) == 0)
  346.         {
  347.             x = READ_WORD(&videoram[offs+4]);
  348.             if (x & 0x4000)
  349.             {
  350.                 scrollx = 0;
  351.                 scrolly = 0;
  352.             }
  353.             else
  354.             {
  355.                 scrollx = scroll1x;
  356.                 scrolly = scroll1y;
  357.             }
  358.             x &= 0x1ff;
  359.             y = READ_WORD(&videoram[offs+6]) & 0x01ff;
  360.             color = READ_WORD(&videoram[offs+8]) & 0x00ff;
  361.  
  362.             xcurrent = x;
  363.             ycurrent = y;
  364.         }
  365.         else
  366.         {
  367.             if ((spritecont & 0x10) == 0)
  368.                 y = ycurrent;
  369.             else if ((spritecont & 0x20) != 0)
  370.                 y += 16;
  371.  
  372.             if ((spritecont & 0x40) == 0)
  373.                 x = xcurrent;
  374.             else if ((spritecont & 0x80) != 0)
  375.                 x += 16;
  376.         }
  377.  
  378.         code = READ_WORD(&videoram[offs]) & 0x1fff;
  379.         if (!code) continue;
  380.  
  381.         {
  382.             int bank;
  383.  
  384.             bank = (code & 0x1c00) >> 10;
  385.             code = spritebank[bank] + (code & 0x3ff);
  386.         }
  387.  
  388.         flipx = spritecont & 0x01;
  389.         flipy = spritecont & 0x02;
  390.  
  391.         // AJP (fixes sprites off right side of screen)
  392.         curx = (x + scrollx) & 0x1ff;
  393.         if (curx>0x140) curx -= 0x200;
  394.         cury = (y + scrolly) & 0x1ff;
  395.         if (cury>0x100) cury -= 0x200;
  396.  
  397.         if (color!=0xff)
  398.         {
  399.             drawgfx (bitmap,Machine->gfx[0],
  400.                 code,
  401.                 color,
  402.                 flipx,flipy,
  403.                 curx,cury,
  404.                 0,TRANSPARENCY_PEN,0);
  405.         }
  406.         else
  407.         {
  408.             // Mask sprite
  409.             struct rectangle myclip;
  410.             int tscrollx, tscrolly;
  411.  
  412.             myclip.min_x = curx;
  413.             myclip.max_x = curx+15;
  414.             myclip.min_y = cury;
  415.             myclip.max_y = cury+15;
  416.             tscrollx = READ_WORD (&taitof2_scrollx[0]) - ((READ_WORD (&videoram[0x14])&0x7f)-0x50);
  417.             tscrolly = READ_WORD (&taitof2_scrolly[0]) - 8;
  418.             copyscrollbitmap (tmpbitmap3,tmpbitmap,1,&tscrollx,1,&tscrolly,&myclip,TRANSPARENCY_NONE,0);
  419.  
  420.             tscrollx = READ_WORD (&taitof2_scrollx[2]) - ((READ_WORD (&videoram[0x14])&0x7f)-0x50);
  421.             tscrolly = READ_WORD (&taitof2_scrolly[2]) - 8;
  422.             copyscrollbitmap (tmpbitmap3,tmpbitmap2,1,&tscrollx,1,&tscrolly,&myclip,TRANSPARENCY_PEN,palette_transparent_pen);
  423.  
  424.             drawgfx (tmpbitmap3,Machine->gfx[0],
  425.                 code,
  426.                 color,
  427.                 flipx,flipy,
  428.                 curx,cury,
  429.                 0,TRANSPARENCY_PEN,15);
  430.  
  431.             copybitmap (bitmap,tmpbitmap3,0,0,0,0,&myclip,TRANSPARENCY_PEN,palette_transparent_pen);
  432.  
  433.         }
  434.     }
  435. }
  436.  
  437. void taitof2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  438. {
  439.     int offs;
  440.     int scrollx, scrolly;
  441.  
  442.     taitof2_update_palette ();
  443.  
  444.     /* Do the background layer */
  445.     // This first pair seems to work only when video flip is on
  446. //    scrollx = READ_WORD(&taitof2_scrollx[0]) - READ_WORD(&taitof2_scrollx[4]);
  447. //    scrolly = READ_WORD(&taitof2_scrolly[0]) - READ_WORD(&taitof2_scrolly[4]);
  448.     scrollx = READ_WORD(&taitof2_scrollx[0]) - ((READ_WORD(&videoram[0x14])&0x7f)-0x50);
  449.     scrolly = READ_WORD(&taitof2_scrolly[0]) - 8;
  450.  
  451.     for (offs = 0;offs < f2_backgroundram_size;offs += 4)
  452.     {
  453.         int tile, color, flipx, flipy;
  454.  
  455.         tile = READ_WORD (&f2_backgroundram[offs + 2]);
  456.         color = (READ_WORD (&f2_backgroundram[offs]) & 0xff);
  457.         flipy = (READ_WORD (&f2_backgroundram[offs]) & 0x8000);
  458.         flipx = (READ_WORD (&f2_backgroundram[offs]) & 0x4000);
  459.  
  460.         if (bg_dirty[offs/4])
  461.         {
  462.             int sx,sy;
  463.  
  464.  
  465.             bg_dirty[offs/4] = 0;
  466.  
  467.             sy = (offs/4) / 64;
  468.             sx = (offs/4) % 64;
  469.  
  470.             drawgfx(tmpbitmap,Machine->gfx[1],
  471.                 tile,
  472.                 color,
  473.                 flipx,flipy,
  474.                 8*sx,8*sy,
  475.                 0,TRANSPARENCY_NONE,0);
  476.         }
  477.     }
  478.  
  479.     copyscrollbitmap(bitmap,tmpbitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  480.  
  481.     /* Do the foreground layer */
  482.     // This first pair seems to work only when video flip is on
  483. //    scrollx = READ_WORD(&taitof2_scrollx[2]) - READ_WORD(&taitof2_scrollx[4]);
  484. //    scrolly = READ_WORD(&taitof2_scrolly[2]) - READ_WORD(&taitof2_scrolly[4]);
  485.     scrollx = READ_WORD(&taitof2_scrollx[2]) - ((READ_WORD(&videoram[0x14])&0x7f)-0x50);
  486.     scrolly = READ_WORD(&taitof2_scrolly[2]) - 8;
  487.  
  488.     for (offs = 0;offs < f2_foregroundram_size;offs += 4)
  489.     {
  490.         int tile, color, flipx, flipy;
  491.  
  492.         tile = READ_WORD (&f2_foregroundram[offs + 2]);
  493.         color = (READ_WORD (&f2_foregroundram[offs]) & 0xff);
  494.         flipy = (READ_WORD (&f2_foregroundram[offs]) & 0x8000);
  495.         flipx = (READ_WORD (&f2_foregroundram[offs]) & 0x4000);
  496.  
  497.         if (fg_dirty[offs/4])
  498.         {
  499.             int sx,sy;
  500.  
  501.  
  502.             fg_dirty[offs/4] = 0;
  503.  
  504.             sy = (offs/4) / 64;
  505.             sx = (offs/4) % 64;
  506.  
  507.             drawgfx(tmpbitmap2,Machine->gfx[1],
  508.                 tile,
  509.                 color,
  510.                 flipy,flipy,
  511.                 8*sx,8*sy,
  512.                 0,TRANSPARENCY_NONE,0);
  513.         }
  514.     }
  515.  
  516.     copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  517.  
  518.     taitof2_draw_sprites (bitmap);
  519.  
  520.     /* Decode any characters that have changed */
  521.     {
  522.         int i;
  523.  
  524.         for (i = 0; i < 256; i ++)
  525.         {
  526.             if (char_dirty[i])
  527.             {
  528.                 decodechar (Machine->gfx[2],i,taitof2_characterram, Machine->drv->gfxdecodeinfo[2].gfxlayout);
  529.                 char_dirty[i] = 0;
  530.             }
  531.         }
  532.     }
  533.  
  534.     for (offs = 0;offs < 0x1000;offs += 2)
  535.     {
  536.         int tile, color, flipx, flipy;
  537.  
  538.         tile = READ_WORD (&f2_textram[offs]) & 0xff;
  539.         if (!tile) continue;
  540.  
  541.         color = (READ_WORD (&f2_textram[offs]) & 0x0f00) >> 8;
  542.         flipy = (READ_WORD (&f2_textram[offs]) & 0x8000);
  543.         flipx = (READ_WORD (&f2_textram[offs]) & 0x4000);
  544.  
  545. //        if (text_dirty[offs/2] || char_dirty[tile])
  546.         {
  547.             int sx,sy;
  548.  
  549.  
  550. //            text_dirty[offs/2] = 0;
  551. //            char_dirty[tile] = 0;
  552.  
  553.             sy = (offs/2) / 64;
  554.             sx = (offs/2) % 64;
  555.  
  556.             drawgfx(bitmap,Machine->gfx[2],
  557.                 tile,
  558.                 color*4,
  559.                 flipx,flipy,
  560.                 8*sx,8*sy,
  561.                 0,TRANSPARENCY_PEN,0);
  562.         }
  563.     }
  564.  
  565. //    copyscrollbitmap(bitmap,tmpbitmap3,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  566.  
  567. }
  568.  
  569.